<template>
  <div class="person-transfer-container">
    <div class="panel left-panel">
      <div class="panel-header">
        <span>候选人</span>
      </div>
      <div class="panel-body">
        <el-input
          v-model="filterText"
          placeholder="按姓名搜索"
          clearable
          class="filter-input"
        />
        <el-tree
          ref="treeRef"
          :data="props.data"
          :props="treeProps"
          show-checkbox
          node-key="userId"
          :default-expand-all="true"
          :filter-node-method="filterNode"
          @check="handleLeftCheckChange"
        >
          <template #default="{ node, data }">
            <div class="custom-tree-node">
              <template v-if="data.deptId">
                <el-icon><Folder /></el-icon>
                <span class="node-label">{{ node.label }}</span>
              </template>
              <template v-else>
                <div class="user-node">
                  <div class="user-info">
                    <el-icon><User /></el-icon>
                    <span class="node-label">{{ node.label }}</span>
                  </div>
                  <div class="user-actions">
                    <el-button link type="primary" @click.stop="viewUser(data)">
                      view
                    </el-button>
                  </div>
                </div>
              </template>
            </div>
          </template>
        </el-tree>
      </div>
      <div class="panel-footer">
        <el-checkbox
          v-model="isAllSelected"
          @change="handleSelectAll"
          :indeterminate="isIndeterminate"
        >
          全选/反选
        </el-checkbox>
      </div>
    </div>

    <div class="center-panel">
      <el-button
        type="primary"
        @click="pushToRight"
        :disabled="leftCheckedUsers.length === 0"
      >
        <el-icon><ArrowRightBold /></el-icon>
        推送
      </el-button>
      <el-button
        type="primary"
        @click="withdrawFromRight"
        :disabled="rightCheckedUsers.length === 0"
      >
        <el-icon><ArrowLeftBold /></el-icon>
        撤回
      </el-button>
    </div>
    <div class="panel right-panel">
      <div class="panel-header">
        <span>已选人员 ({{ rightData.length }}人)</span>
      </div>
      <div class="panel-body">
        <el-table
          ref="tableRef"
          :data="rightData"
          style="width: 100%"
          height="100%"
          @selection-change="handleRightSelectionChange"
        >
          <el-table-column type="selection" width="55" />
          <el-table-column label="姓名">
            <template #default="{ row }">
              <div class="user-cell">
                <el-icon><UserFilled /></el-icon>
                <span>{{ row.userName }}</span>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="100">
            <template #default="{ row }">
              <el-button link type="primary" @click="viewUser(row)">
                <el-icon><View /></el-icon>
              </el-button>
              <el-button link type="danger" @click="deleteFromRight(row)">
                <el-icon><Delete /></el-icon>
              </el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div class="panel-footer">
        <el-checkbox
          v-model="isRightAllSelected"
          @change="handleRightSelectAll"
          :disabled="rightData.length === 0"
        >
          全选
        </el-checkbox>
      </div>
    </div>
    <el-dialog v-model="dialogVisible" title="人员详情" width="30%">
      <div v-if="currentUser">
        <p><strong>姓名:</strong> {{ currentUser.userName }}</p>
        <p><strong>年龄:</strong> {{ currentUser.age }}</p>
        <p><strong>性别:</strong> {{ currentUser.gender }}</p>
        <p><strong>ID:</strong> {{ currentUser.userId }}</p>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">关闭</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, watch, computed } from "vue";
import {
  Folder,
  User,
  View,
  Delete,
  ArrowRightBold,
  ArrowLeftBold,
  UserFilled,
} from "@element-plus/icons-vue";
import type { ElTree, ElTable } from "element-plus";
import type { CheckboxValueType } from "element-plus";

// --- 类型定义 ---
interface User {
  userId: string;
  userName: string;
  age: number;
  gender: string;
}
interface Department {
  dept: string;
  deptId: string;
  children: User[];
}

// --- Props ---
const props = defineProps<{
  data: Department[];
}>();

// --- Refs and Reactive State ---
const treeRef = ref<InstanceType<typeof ElTree>>();
const tableRef = ref<InstanceType<typeof ElTable>>();
const filterText = ref("");
const rightData = ref<User[]>([]);
const leftCheckedUsers = ref<User[]>([]);
const rightCheckedUsers = ref<User[]>([]);
const dialogVisible = ref(false);
const currentUser = ref<User | null>(null);

// ★ 步骤2: 重写 treeProps，将 disabled 改为函数
const treeProps = {
  label: (data: any) => data.dept || data.userName,
  children: "children",
  disabled: (data: any) => {
    // 只有用户节点（有userId）才需要判断是否禁用
    // data.userId && rightUserIds.value.has(data.userId)
    // 检查 data 对象自身是否含有 userId 属性，避免访问原型链
    return (
      Object.prototype.hasOwnProperty.call(data, "userId") &&
      rightUserIds.value.has(data.userId)
    );
  },
};

// --- Computed Properties ---
const rightUserIds = computed(
  () => new Set(rightData.value.map((user) => user.userId))
);

// ★ 步骤3: 删除 leftTreeData 计算属性

const allUserNodes = computed(() =>
  props.data.flatMap((dept) => dept.children || [])
);
const availableUsers = computed(() =>
  allUserNodes.value.filter((user) => !rightUserIds.value.has(user.userId))
);
const isAllSelected = computed({
  get: () => {
    const availableAndChecked = leftCheckedUsers.value.filter(
      (u) => !rightUserIds.value.has(u.userId)
    );
    return (
      availableUsers.value.length > 0 &&
      availableAndChecked.length === availableUsers.value.length
    );
  },
  set: (val) => {
    if (val) {
      const availableIds = availableUsers.value.map((u) => u.userId);
      treeRef.value?.setCheckedKeys([
        ...Array.from(rightUserIds.value),
        ...availableIds,
      ]);
    } else {
      treeRef.value?.setCheckedKeys(Array.from(rightUserIds.value));
    }
    handleLeftCheckChange();
  },
});
const isIndeterminate = computed(() => {
  const availableAndCheckedCount = leftCheckedUsers.value.filter(
    (u) => !rightUserIds.value.has(u.userId)
  ).length;
  return (
    availableAndCheckedCount > 0 &&
    availableAndCheckedCount < availableUsers.value.length
  );
});
const isRightAllSelected = ref(false);

// --- Watchers ---
watch(rightUserIds, (newIds) => {
  // 当右侧列表变化时，左侧树的勾选状态和禁用状态都会自动响应，
  // 但为了保持勾选状态同步，我们仍然需要显式设置勾选的 keys。
  if (treeRef.value) {
    treeRef.value.setCheckedKeys(Array.from(newIds));
  }
});

watch(filterText, (val) => {
  treeRef.value!.filter(val);
});

// --- Methods (无变化) ---
const filterNode = (value: string, data: any) => {
  if (!value) return true;
  return data.userName?.includes(value);
};

const handleLeftCheckChange = () => {
  const allCheckedNodes =
    (treeRef.value?.getCheckedNodes(true) as User[]) || [];
  leftCheckedUsers.value = allCheckedNodes.filter(
    (node) => !rightUserIds.value.has(node.userId)
  );
};

const handleSelectAll = (val: CheckboxValueType) => {
  isAllSelected.value = !!val;
};

const handleRightSelectionChange = (selection: User[]) => {
  rightCheckedUsers.value = selection;
  isRightAllSelected.value =
    selection.length > 0 &&
    rightData.value.length > 0 &&
    selection.length === rightData.value.length;
};

const handleRightSelectAll = (val: CheckboxValueType) => {
  if (val) {
    tableRef.value?.clearSelection();
    rightData.value.forEach((row) => {
      tableRef.value?.toggleRowSelection(row, true);
    });
  } else {
    tableRef.value?.clearSelection();
  }
};

const pushToRight = () => {
  if (leftCheckedUsers.value.length === 0) return;
  rightData.value.push(...leftCheckedUsers.value);
  leftCheckedUsers.value = [];
};

const withdrawFromRight = () => {
  if (rightCheckedUsers.value.length === 0) return;
  const idsToRemove = new Set(
    rightCheckedUsers.value.map((user) => user.userId)
  );
  rightData.value = rightData.value.filter(
    (user) => !idsToRemove.has(user.userId)
  );
  rightCheckedUsers.value = [];
};

const deleteFromRight = (user: User) => {
  const index = rightData.value.findIndex((u) => u.userId === user.userId);
  if (index !== -1) rightData.value.splice(index, 1);
};

const viewUser = (user: User) => {
  currentUser.value = user;
  dialogVisible.value = true;
};

// 暴露方法给父组件
defineExpose({
  getSelectedData: () => {
    return rightData.value;
  },
});
</script>

<style scoped>
.person-transfer-container {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  height: 500px;
}
.panel {
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  width: 40%;
  height: 100%;
  display: flex;
  flex-direction: column;
}
.panel-header {
  background-color: #f5f7fa;
  padding: 8px 15px;
  border-bottom: 1px solid #dcdfe6;
  font-weight: bold;
}
.panel-body {
  flex-grow: 1;
  overflow: auto;
  padding: 10px;
}
.panel-footer {
  padding: 8px 15px;
  border-top: 1px solid #ebeef5;
}
.filter-input {
  margin-bottom: 10px;
}
.center-panel {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width: 15%;
}
.center-panel .el-button {
  margin: 10px 0;
}
.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}
.node-label {
  margin-left: 5px;
}
.user-node {
  display: flex;
  width: 100%;
  justify-content: space-between;
  align-items: center;
}
.user-info,
.user-cell {
  display: flex;
  align-items: center;
}
.user-info .el-icon,
.user-cell .el-icon {
  margin-right: 5px;
}
.el-tree {
  min-width: 100%;
  display: inline-block !important;
}
</style>
